﻿using System;
using BusinessBingo.CommandHandlers.Base;
using BusinessBingo.CommandHandlers.Interfaces;
using BusinessBingo.CommandHandlers.Results;
using BusinessBingo.Commands;
using BusinessBingo.Data.Interfaces;
using BusinessBingo.Model;
using BusinessBingo.Model.Interfaces;

namespace BusinessBingo.CommandHandlers
{
    public class CreateBingoSetCommandHandler :
        BaseCommandHandler,
        ICreateBingoSetCommandHandler
    {
        private IBingoSetRepository _bingoSetRepository;

        public CreateBingoSetCommandHandler(
            IBingoSetRepository bingoSetRepository,
            IValidationState validationState,
            IUnitOfWork unitOfWork)
            : base(validationState, unitOfWork)
        {
            this._bingoSetRepository = bingoSetRepository;
        }

        public CreateBingoSetCommandHandlerResult Execute(CreateBingoSetCommand createBingoSetCommand)
        {
            CreateBingoSetCommandHandlerResult result = new CreateBingoSetCommandHandlerResult();

            if (createBingoSetCommand == default(CreateBingoSetCommand))
                throw new ArgumentNullException("CreateBingoSetCommand");

            if (createBingoSetCommand.BingoSet == default(BingoSet))
                this._validationState.AddError<CreateBingoSetCommand>(x => x.BingoSet, ErrorTypes.Empty);
            else
            {
                double sqrt = Math.Sqrt(createBingoSetCommand.BingoSet.WordPositions.Count);
                if (createBingoSetCommand.BingoSet.WordPositions.Count % sqrt != 0)
                    this._validationState.AddError<CreateBingoSetCommand>(x => x.BingoSet, ErrorTypes.Invalid);
            }
            if (createBingoSetCommand.UserId == default(Guid))
                this._validationState.AddError<CreateBingoSetCommand>(x => x.UserId, ErrorTypes.Empty);

            if (createBingoSetCommand.GameId == default(Guid))
                this._validationState.AddError<CreateBingoSetCommand>(x => x.GameId, ErrorTypes.Empty);
            
            if (this._validationState.IsValid == false) return result;

            BingoSet bingoSet = createBingoSetCommand.BingoSet;
            bingoSet.UserId = createBingoSetCommand.UserId;
            bingoSet.GameId = createBingoSetCommand.GameId;
            this._bingoSetRepository.AddItem(bingoSet);

            this.Complete();

            result.Succeeded = true;

            return result;
        }
    }
}